<script setup lang="ts" name="InfraConfigForm">
import { storeToRefs } from 'pinia'
import { useAppStoreWithOut } from '@/store/modules/app'
import { ConfigApi, ConfigType } from '@/api/infra/config'
import { DICT_TYPE } from '@/enums/dictEnums'
import { getStrDictOptions, getBoolDictOptions } from '@/utils/dict'
import { isArray } from '@/utils/is'
const appStore = useAppStoreWithOut()
const { systemConfig } = storeToRefs(appStore)

const { t } = useI18n() // 国际化
const message = useMessage() // 消息弹窗

const visible = ref(false) // 弹窗的是否展示
const title = ref('') // 弹窗的标题
const formLoading = ref(false) // 表单的加载中：1）修改时的数据加载；2）提交的按钮禁用
const formType = ref('') // 表单的类型：create - 新增；update - 修改
const formData = ref({
  id: undefined,
  category: '',
  name: '',
  key: '',
  type: 'string',
  dateType: 'datetime' as any,
  isTimerange: false,
  value: undefined as any,
  remark: ''
})
const formRules = reactive({
  category: [{ required: true, message: t('infra.config.rules', 'category'), trigger: 'blur' }],
  name: [{ required: true, message: t('infra.config.rules', 'name'), trigger: 'blur' }],
  key: [{ required: true, message: t('infra.config.rules', 'key'), trigger: 'blur' }],
  type: [{ required: true, message: t('infra.config.rules', 'type'), trigger: 'blur' }],
  value: [{ required: true, message: t('infra.config.rules', 'value'), trigger: 'blur' }]
})
const formRef = ref() // 表单 Ref

/** 打开弹窗 */
const open = async (type: string, id?: number) => {
  visible.value = true
  title.value = t('action', type)
  formType.value = type
  resetForm()
  // 修改时，设置数据
  if (id) {
    formLoading.value = true
    try {
      formData.value = await ConfigApi.detail(id)
    } finally {
      formLoading.value = false
    }
  }
}
defineExpose({ open }) // 提供 open 方法，用于打开弹窗

/** 提交表单 */
const emit = defineEmits(['success']) // 定义 success 事件，用于操作成功后的回调
const submitForm = async () => {
  // 校验表单
  if (!formRef) return
  const valid = await formRef.value.validate()
  if (!valid) return
  // 提交请求
  formLoading.value = true
  try {
    const data = formData.value as unknown as ConfigType
    if (formType.value === 'create') {
      await ConfigApi.create(data)
      message.success(t('message', 'createSuccess'))
    } else {
      await ConfigApi.update(data)
      message.success(t('message', 'updateSuccess'))
    }
    visible.value = false
    // 发送操作成功的事件
    emit('success')
  } finally {
    formLoading.value = false
  }
}

/** 重置表单 */
const resetForm = () => {
  formData.value = {
    id: undefined,
    category: '',
    name: '',
    key: '',
    type: 'string',
    dateType: 'datetime' as any,
    isTimerange: false,
    value: undefined as any,
    remark: ''
  }
  formRef.value?.resetFields()
}

// 参数类型改变事件
const handleTypeChange = (v) => {
  switch (v) {
    case 'string':
      formData.value.value = ''
      break
    case 'number':
      formData.value.value = 0
      break
    case 'date':
      formData.value.dateType = 'datetime'
      formData.value.value = ''
      break
    case 'time':
      formData.value.isTimerange = false
      formData.value.value = ''
      break
    case 'color':
      formData.value.value = ''
      break
    default:
      break
  }
}

// 日期类型改变事件
const handleDateTypeChange = (v) => {
  if (v === 'year' || v === 'month' || v === 'date' || v === 'datetime' || v === 'week') {
    formData.value.value = ''
  } else {
    formData.value.value = []
  }
}

// 是否时间范围改变事件
const handleTimeRangeChange = (v) => {
  if (v) {
    formData.value.value = []
  } else {
    formData.value.value = ''
  }
}

// 日期的值格式化事件
const dateValueFormat = computed(() => {
  if (formData.value.dateType === 'year' || formData.value.dateType === 'years' || formData.value.dateType === 'yearrange') {
    return 'YYYY'
  } else if (formData.value.dateType === 'month' || formData.value.dateType === 'months' || formData.value.dateType === 'monthrange') {
    return 'YYYY-MM'
  } else if (formData.value.dateType === 'date' || formData.value.dateType === 'dates') {
    return 'YYYY-MM-DD'
  } else {
    return 'YYYY-MM-DD HH:mm:ss'
  }
})
</script>

<template>
  <Dialog v-model="visible" :title="title" width="600px">
    <el-form ref="formRef" v-loading="formLoading && systemConfig.loadingType === 'module'" :model="formData" :rules="formRules" label-width="80px">
      <el-form-item :label="t('infra.config', 'category')" prop="category">
        <el-input v-model="formData.category" clearable :placeholder="t('infra.config.rules', 'category')" />
      </el-form-item>
      <el-form-item :label="t('infra.config', 'name')" prop="name">
        <el-input v-model="formData.name" clearable :placeholder="t('infra.config.rules', 'name')" />
      </el-form-item>
      <el-form-item :label="t('infra.config', 'key')" prop="key">
        <el-input v-model="formData.key" clearable :placeholder="t('infra.config.rules', 'key')" />
      </el-form-item>
      <ElFormItem :label="t('infra.config', 'type')">
        <el-select v-model="formData.type" :placeholder="t('infra.config.rules', 'type')" @change="handleTypeChange">
          <el-option v-for="dict in getStrDictOptions(DICT_TYPE.INFRA_CONFIG_VALUE_TYPE)" :key="dict.value" :label="dict.label" :value="dict.value" />
        </el-select>
      </ElFormItem>
      <ElFormItem v-if="formData.type === 'date'" :label="t('infra.config', 'dateType')">
        <el-select v-model="formData.dateType" :placeholder="t('infra.config.rules', 'dateType')" @change="handleDateTypeChange">
          <el-option v-for="dict in getStrDictOptions(DICT_TYPE.INFRA_CONFIG_DATE_TYPE)" :key="dict.value" :label="dict.label" :value="dict.value" />
        </el-select>
      </ElFormItem>
      <ElFormItem v-if="formData.type === 'time'" :label="t('infra.config', 'isTiemrange')">
        <el-radio-group v-model="formData.isTimerange" class="radio-button" @change="handleTimeRangeChange">
          <el-radio-button v-for="(item, index) in getBoolDictOptions(DICT_TYPE.INFRA_BOOLEAN_STRING)" :key="index" :value="item.value" border>
            {{ item.label }}
          </el-radio-button>
        </el-radio-group>
      </ElFormItem>
      <el-form-item v-if="formData.type === 'string'" :label="t('infra.config', 'value')" prop="value">
        <el-input v-model="formData.value" clearable :placeholder="t('infra.config.rules', 'value')" type="textarea" />
      </el-form-item>
      <el-form-item v-if="formData.type === 'number'" :label="t('infra.config', 'value')" prop="value">
        <el-input-number v-model="formData.value" clearable />
      </el-form-item>
      <el-form-item v-if="formData.type === 'date'" :label="t('infra.config', 'value')" prop="value">
        <el-date-picker
          v-if="formData.dateType === 'year' || formData.dateType === 'month' || formData.dateType === 'date' || formData.dateType === 'datetime' || formData.dateType === 'week'"
          key="a"
          v-model="formData.value"
          clearable
          :placeholder="t('infra.config.rules', 'date')"
          :type="formData.dateType"
          :value-format="dateValueFormat"
          class="flex-1" />
        <el-date-picker v-else-if="formData.dateType === 'years' || formData.dateType === 'months' || formData.dateType === 'dates'" key="b" v-model="formData.value" clearable :placeholder="t('infra.config.rules', 'date')" :type="formData.dateType" :value-format="dateValueFormat" class="flex-1" />
        <el-date-picker
          v-else
          key="c"
          v-model="formData.value"
          :default-time="[new Date('1 00:00:00'), new Date('1 23:59:59')]"
          clearable
          :start-placeholder="t('common', 'startDate')"
          :end-placeholder="t('common', 'endDate')"
          :type="formData.dateType"
          :value-format="dateValueFormat"
          class="flex-1" />
      </el-form-item>
      <el-form-item v-if="formData.type === 'time'" :label="t('infra.config', 'value')" prop="value">
        <el-time-picker v-if="formData.isTimerange && isArray(formData.value)" v-model="formData.value" value-format="HH:mm:ss" clearable is-range :start-placeholder="t('common', 'startTime')" :end-placeholder="t('common', 'endTime')" class="flex-1" />
        <el-time-picker v-if="!isArray(formData.value) && !formData.isTimerange" v-model="formData.value" value-format="HH:mm:ss" clearable :placeholder="t('infra.config.rules', 'time')" class="flex-1" />
      </el-form-item>
      <el-form-item v-if="formData.type === 'color'" :label="t('infra.config', 'value')" prop="value">
        <ColorInput v-model="formData.value" show-alpha />
      </el-form-item>
      <el-form-item :label="t('common', 'remark')" prop="remark">
        <el-input v-model="formData.remark" clearable :placeholder="t('common.rules', 'remark')" type="textarea" />
      </el-form-item>
    </el-form>
    <template #footer>
      <el-button @click="visible = false">{{ t('action', 'cancel') }}</el-button>
      <el-button :disabled="formLoading" type="primary" @click="submitForm">{{ t('action', 'confirm') }}</el-button>
    </template>
  </Dialog>
</template>

<style scoped lang="scss">
.el-form{
  margin-right: -6px;
}
</style>
